package org.xmx0632.test.jmeter.longtcp;

import java.util.concurrent.atomic.AtomicLong;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.xmx0632.test.jmeter.longtcp.util.SocketClient;
import org.xmx0632.test.jmeter.longtcp.util.Variables;

public class TcpRequest extends AbstractJavaSamplerClient {
	private static AtomicLong setupCounter = new AtomicLong(0);
	private static AtomicLong teardownCounter = new AtomicLong(0);

	// private AtomicLong requestCounter = new AtomicLong(0);

	private Arguments args;
	// private SocketClient client;
	// private static ThreadLocal<Variables> local = new
	// ThreadLocal<Variables>();
	private Variables local = null;
	private boolean registered = false;

	public Arguments getDefaultParameters() {
		this.args = new Arguments();
		this.args.addArgument("host", "172.16.161.76");
		this.args.addArgument("port", "2002");
		this.args.addArgument("accessKey", "1234567890abcdef");
		this.args.addArgument("register", "");
		this.args.addArgument("heartbeat", "");
		this.args.addArgument("data", "");

		String registerExample = "{\"code\":\"0001\", \"gateway\":{\"gatewayId\":\"1@1\"},\"timestamp\":1457665955,\"version\":\"0.0.1\"}";
		this.args.addArgument("register-example(例子没用)", registerExample);

		String heartbeatExample = "{\"code\":\"0002\",\"gateway\":{\"gatewayId\":\"1@1\"},\"timestamp\":1457666227,\"version\":\"0.0.1\"}";
		this.args.addArgument("heartbeat-example(例子没用)", heartbeatExample);

		String reportDataExample = "{\"code\":\"A002\",\"sequence\":\"a89e10\",\"deviceList\":[{\"deviceId\":\"1@1\",\"stream\":[{\"atnumber\":\"A0012\",\"strvalue\":\"0\"}]}],\"gateway\":{\"gatewayId\":\"1@1\"},\"timestamp\":1457666262,\"version\":\"0.0.1\"}";
		this.args.addArgument("report-data-example(例子没用)", reportDataExample);

		String alarmDataExample = "{\"code\":\"A001\",\"gateway\":{\"gatewayId\":\"1@1\"},\"streams\":[{\"deviceId\":\"1@1\",\"warnings\":[{\"atnumber\":\"A0012\",\"strvalue\":\"str123\"}]}],\"timestamp\":1457666358,\"version\":\"0.0.1\"}";
		this.args.addArgument("alarm-data-example(例子没用)", alarmDataExample);
		return this.args;
	}

	public void setupTest(JavaSamplerContext context) {
		long currentSetupCounter = setupCounter.incrementAndGet();
		System.out.println("=== SetupCounter===:" + currentSetupCounter);

		// 建立连接
		String threadId = Thread.currentThread().getName() + "@" + Thread.currentThread().getId();
		String host = context.getParameter("host");
		int port = Integer.parseInt(context.getParameter("port"));
		String accessKey = context.getParameter("accessKey");
		long currentTimestamp = System.currentTimeMillis() / 1000L;

		local = new Variables();
		SocketClient client = null;
		try {
			client = new SocketClient(host, port, accessKey, threadId);
		} catch (Exception e) {
			e.printStackTrace();
		}
		local.setClient(client);
		local.setTimestamp(currentTimestamp);

		super.setupTest(context);
	}

	public void teardownTest(JavaSamplerContext context) {
		long currentTeardown = teardownCounter.incrementAndGet();
		System.out.println("=== Teardown===:" + currentTeardown);
		if (local.getClient() != null) {
			local.getClient().closeSocket();
		}

		super.teardownTest(context);
	}

	public SampleResult runTest(JavaSamplerContext arg0) {
		SampleResult sr = new SampleResult();
		sr.setDataType("text");
		sr.sampleStart();

		try {
			String register = arg0.getParameter("register");
			String heartbeat = arg0.getParameter("heartbeat");
			String data = arg0.getParameter("data");
			long currentTimestamp = System.currentTimeMillis() / 1000L;
			if (!registered) {
				registered = true;
				sendData(sr, register);
				sr.setSampleLabel("register");
				sr.sampleEnd();
				return sr;
			} else {// send heartbeat
				long lastTimestamp = local.getTimestamp();
				if (currentTimestamp - lastTimestamp > 10L) {
					local.setTimestamp(currentTimestamp);
					sendData(sr, heartbeat);
					sr.setSampleLabel("heartbeat");
					sr.sampleEnd();
					return sr;
				}
			}
			sendData(sr, data);
			sr.setSampleLabel("report");
			sr.sampleEnd();
			return sr;
		} catch (Exception e) {
			e.printStackTrace();
			sr.setSuccessful(false);
			sr.setResponseMessage("ERROR:" + e.getMessage());
			sr.setResponseCode("502");
			sr.sampleEnd();
		}
		return sr;
	}

	private String sendData(SampleResult sr, String data) {
		String result = "failed";
		try {
			result = local.getClient().sendMsg(data);
			// System.out.println("send data result:" + result);

			sr.setSamplerData(data);
			sr.setResponseData(result, "UTF-8");
			sr.setResponseMessage("SUCCESS");
			sr.setResponseCodeOK();
			sr.setSuccessful(true);

		} catch (Exception e) {
			e.printStackTrace();
			sr.setSuccessful(false);
			sr.setResponseMessage("ERROR:" + e.getMessage());
			sr.setResponseCode("501");
		}
		return result;
	}
}
